home *** CD-ROM | disk | FTP | other *** search
- procedure UNCRUNCH (var Addr1,Addr2; BlkLen:Integer);
-
- {This is the flash display routine used to display crunched TheDraw image
- files. It uses a custom protocol for reproducing a image with any
- possible color combinations. The control codes below #32 are reserved
- for this function. The following data structure shows the format of a
- sequence. Not all operations use the optional bytes <x> or <y>..
-
- Data Structure: <current byte>[<x>[<y>]]
-
- 0..15 = New Foreground Color
- 16..23 = New Background Color
- 24 = Go down to next line, return to same horizontal position as when
- routine was started (akin to a c/r).
- 25 = Displays <x> number of spaces.
- 26 = Displays <x> number of <y>. Also used to display ANY characters
- below #32. This function is the only way to do this although it
- uses three bytes. Otherwise the character would be interpreted
- as another command code.
- 27 = Toggles on/off the foreground attribute blink flag.
-
-
- ----------------------------------------------------------------------------
-
- To use this routine you call the procedure with the ImageData as the
- first parameter, the display address as the second parameter, and the
- length of the ImageData as the third parameter.
-
- Assume we have a ImageData file of a 40 character by 10 line block. Also
- the following defintions. ie:
-
- type ScreenType = array [0..3999] of Byte;
- var ScreenAddr : ScreenType absolute $B800:$0000;
-
- const ImageData : array [1..467] of Byte =
- (...list of image bytes here...);
-
- begin
- UnCrunch (ImageData,ScreenAddr[ (34*2) + (5*160) -162],467);
- end;
-
-
- SCREENADDR is a variable mapped to the same location as the physical video
- addresses (using Turbo's absolute addressing). The fairly complex array
- address in the call tells UnCrunch where to start displaying the ImageData
- 40 character by 10 line block. The 34*2 indicates the horizontal position
- number 34 with the 5*160 indicating line number 5. This is similar to a
- Turbo GOTOXY (34,5) statement, except it works for UnCrunch instead.
-
- The value of 467 used in the call is the length of the array as indicated
- in the CONST statement.
-
- UnCrunch remembers the horizontal (X) starting position when it goes down
- to the next line. This allows you to display the ImageData block correctly
- at any position on the screen. ie:
-
- +-------------------------------------------------+
- | |
- | | <- Pretend this
- | | is the video
- | ┌─────────────────────┐ | display.
- | │█████████████████████│ |
- | │█████████████████████│ |
- | │██ ImageData block ██│ |
- | │█████████████████████│ |
- | │█████████████████████│ |
- | │█████████████████████│ |
- | └─────────────────────┘ |
- | |
- | |
- | |
- +-------------------------------------------------+
-
-
- The ImageData block could just as well have been display in the upper-left
- corner of the screen with:
- UNCRUNCH (ImageData,ScreenAddr[ (1*2) + (1*160) -162],467);
-
- Notice the array address changed to the equivilant of GOTOXY (1,1);
-
- To display the block in the lower-right corner you would use:
- UNCRUNCH (ImageData,ScreenAddr[ (40*2) + (15*160) -162],467);
-
- The block is 40 characters wide by 10 lines deep. Therefore to display
- such a large block, we must display the block at GOTOXY (40,15);
-
-
- Obviously I have been attempting to describe this procedure by use of
- examples. This was done because I felt it to be the easiest and clearest
- way explaining the procedure. It was designed to be as simple as possible,
- however for some people the best way to learn it is to experiment. Try
- creating a program using the above example information. Use TheDraw to
- make a 40 by 10 block (or any size) to experiment with. Good luck. If
- you can devise a better way of explaining this, please share your labors
- with me. Others will surely benifit. Thanks!
-
- }
- begin
- inline (
- $1E/ { PUSH DS}
- $C5/$B6/Addr1/ { LDS SI,[BP+Addr1] ;Source Address}
- $C4/$BE/Addr2/ { LES DI,[BP+Addr2] ;Destination Addr}
- $8B/$8E/BlkLen/ { MOV CX,[BP+BlkLen] ;Length of block}
- $8B/$D7/ { MOV DX,DI ;Save X coordinate for later.}
- $33/$C0/ { XOR AX,AX ;Set Current attributes.}
- $AC/ {LOOPA: LODSB ;Get next character.}
- $3C/$1B/ { CMP AL,27 ;Does user want to toggle the blink}
- $75/$05/ { JNZ ForeGround ;attibute?}
- $80/$F4/$80/ { XOR AH,128 ;Done.}
- $EB/$4D/ { JMP Short Next}
- {ForeGround:}
- $3C/$10/ { CMP AL,16 ;If less than 16, then change the}
- $73/$07/ { JNC BackGround ;foreground color. Otherwise jump.}
- $80/$E4/$70/ { AND AH,70H ;Strip off old foreground.}
- $0A/$E0/ { OR AH,AL}
- $EB/$42/ { JMP Short Next}
- {BackGround:}
- $3C/$18/ { CMP AL,24 ;If less than 24, then change the}
- $74/$13/ { JZ NextLine ;background color. If exactly 24,}
- $73/$19/ { JNC MultiOutput ;then jump down to next line.}
- $2C/$10/ { SUB AL,16 ;Otherwise jump to multiple output}
- $02/$C0/ { ADD AL,AL ;routines.}
- $02/$C0/ { ADD AL,AL}
- $02/$C0/ { ADD AL,AL}
- $02/$C0/ { ADD AL,AL}
- $80/$E4/$8F/ { AND AH,8FH ;Strip off old background.}
- $0A/$E0/ { OR AH,AL}
- $EB/$2B/ { JMP Short Next}
- {NextLine:}
- $81/$C2/$A0/$00/ { ADD DX,160 ;If equal to 24,}
- $8B/$FA/ { MOV DI,DX ;then jump down to}
- $EB/$23/ { JMP Short Next ;the next line.}
- {MultiOutput:}
- $3C/$19/ { CMP AL,25 ;If equal to 25,}
- $75/$0B/ { JNZ NotMultiSpaces ;then using the}
- $AC/ { LODSB ;following code as}
- $51/ { PUSH CX ;a count, output}
- $32/$ED/ { XOR CH,CH ;said number of}
- $8A/$C8/ { MOV CL,AL ;spaces.}
- $B0/$20/ { MOV AL,32}
- $EB/$0D/$90/ { JMP StartOutput ;Use below loop.}
- {NotMultiSpaces:}
- $3C/$1A/ { CMP AL,26 ;If equal to 26, then using}
- $75/$0F/ { JNZ NormalLetter ;the following two codes, display}
- $AC/ { LODSB ;<x> number of <y> characters.}
- $49/ { DEC CX ;Adjust main counter.}
- $51/ { PUSH CX ;Display as many of}
- $32/$ED/ { XOR CH,CH ;whatever the user}
- $8A/$C8/ { MOV CL,AL ;wants.}
- $AC/ { LODSB ;Get character.}
- {StartOutput:}
- $E3/$03/ { JCXZ Stop ;Abort if already at zilch.}
- $AB/ {LOOPB: STOSW}
- $E2/$FD/ { LOOP LOOPB}
- $59/ {Stop: POP CX}
- $49/ { DEC CX ;Adjust main counter.}
- {NormalLetter:}
- $AB/ { STOSW ;Save screen letter.}
- $E3/$02/ {Next: JCXZ Done ;Get next, unless CX}
- $E2/$A5/ { LOOP LOOPA ;has already one to zero.}
- $1F); {Done: POP DS}
- end; {UNCRUNCH}